/* Contributed by Carpfish
 * 20110201
 */

#ifndef _PRO_PACKED_FONT_
#define _PRO_PACKED_FONT_

#include <nds.h>
#include "fontbase.h"

namespace WoopsiUI {

	/**
	 * PackedFont is a base class defining a font whose data is packed into a
	 * more efficient data format.
	 */
	class PropackFont : public FontBase {
	public:
		/**
		 * Constructor.
		 * @param glyphFileName path of font file .
		 */
		PropackFont(const char *glyphFileName);
		
		/**
		 * Constructor.
		 * @param glyphData font data array.
		 * @param glyphSize size of font data array.
		 */
		PropackFont(const u8 *glyphData,const int glyphSize);
		
		/**
		 * Destructor.
		 */
		virtual inline ~PropackFont() {
			free(_glyphData);_glyphData = NULL;
			free(_glyphTable);_glyphTable = NULL;
		}
		
		/**
		 * Draw an individual character of the font to the specified bitmap.
		 * @param bitmap The bitmap to draw to.
		 * @param letter The character to output.
		 * @param x The x co-ordinate of the text.
		 * @param y The y co-ordinate of the text.
		 * @param clipX1 The left edge of the clipping rectangle.
		 * @param clipY1 The top edge of the clipping rectangle.
		 * @param clipX2 The right edge of the clipping rectangle.
		 * @param clipY2 The bottom edge of the clipping rectangle.
		 * @return The x co-ordinate for the next character to be drawn.
		 */
		virtual s16 drawChar(
			MutableBitmapBase* bitmap,
			u32 letter,
			u16 colour,
			s16 x, s16 y,
			u16 clipX1, u16 clipY1, u16 clipX2, u16 clipY2);
		
		/**
		 * Draw an individual character of the font to the specified bitmap on a baseline.
		 * @param bitmap The bitmap to draw to.
		 * @param letter The character to output.
		 * @param x The x co-ordinate of the text.
		 * @param y The y co-ordinate of the text.
		 * @param clipX1 The left edge of the clipping rectangle.
		 * @param clipY1 The top edge of the clipping rectangle.
		 * @param clipX2 The right edge of the clipping rectangle.
		 * @param clipY2 The bottom edge of the clipping rectangle.
		 * @return The x co-ordinate for the next character to be drawn.
		 */
		virtual s16 drawBaselineChar(
			MutableBitmapBase* bitmap,
			u32 letter,
			u16 colour,
			s16 x, s16 y,
			u16 clipX1, u16 clipY1, u16 clipX2, u16 clipY2) {
		        return drawChar(bitmap,letter,colour,x, y-getCharTop(y),clipX1, clipY1, clipX2, clipY2);
			};			
		
		/**
		 * Get the width of a string in pixels when drawn with this font.
		 * @param text The string to check.
		 * @return The width of the string in pixels.
		 */
		virtual u16 getStringWidth(const WoopsiString& text) const;

		/**
		 * Get the width of a portion of a string in pixels when drawn with this font.
		 * Useful if you want to determine the length of a string without a terminator, or
		 * the length of a section of a string.
		 * @param text The string to check.
		 * @param startIndex The start point of the substring within the string.
		 * @param length The length of the substring in chars.
		 * @return The width of the substring in pixels.
		 */
		virtual u16 getStringWidth(const WoopsiString& text, s32 startIndex, s32 length) const;

		/**
		 * Get the width of an individual character.
		 * @param letter The character to get the width of.
		 * @return The width of the character in pixels.
		 */
		virtual u8 getCharWidth(u32 letter) const;

		/**
		 * Get the top of an individual character (constant for a packedfont).
		 * @param letter The character to get the width of.
		 * @return The width of the character in pixels.
		 */
		inline virtual s8 getCharTop(u32 letter) const {return 0;};
		
		/**
		 * Text uses this to decide whether a given character is blank or not
		 */
		virtual bool isCharBlank(const u32 letter) const;

		/**
		* Gets the height of the font.
		* @return The height of the font.
		*/
		virtual u8 getHeight() const { return _height; };
		
		/**
		* Get the height of an individual character.
		* @param letter The letter to get the height of.
		* @return The height of the character in pixels.
		*/
		virtual u8 getCharHeight(u32 letter) const { return _height; };
		
	protected:
		u8 _height; 			/**< The height of the font. */
		u16 *_glyphData;		/**< All data for each glyph */
		u16 **_glyphTable;		/**< Locations of each character in _glyphData */
		u8 _spWidth;			/**< Width of Padding space */

		/**
		 * Get packed array representing font of the specified character.
		 * @param letter The character to get the font of.
		 */
		u16* GetGlyphData(u32 letter) const;
		
		/**
		 * Render an individual character of the font to the specified bitmap.
		 * @param pixelData The font-specific pixel data
		 * @param pixelsPerRow The number of pixels to render per row (for this character)
		 * @param bitmap The bitmap to draw to.
		 * @param colour The colour of the text.
		 * @param x The x co-ordinate of the text.
		 * @param y The y co-ordinate of the text.
		 * @param clipX1 The left edge of the clipping rectangle.
		 * @param clipY1 The top edge of the clipping rectangle.
		 * @param clipX2 The right edge of the clipping rectangle.
		 * @param clipY2 The bottom edge of the clipping rectangle.
		 */
		void renderChar(
				const u16 *pixelData, u16 pixelsPerRow,
				MutableBitmapBase* bitmap,
				u16 colour,
				s16 x, s16 y,
				u16 clipX1, u16 clipY1, u16 clipX2, u16 clipY2);
	};
}

#endif
